package org.outlook.apps.goal.ui.components.login;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

import org.outlook.apps.goal.action.Authenticater;
import org.outlook.commons.authentocate.LoginEvent;
import org.outlook.commons.authentocate.LoginListener;

public class LoginDialog extends JDialog implements FadeListener {

	private static final long serialVersionUID = 1L;

	private JComponent contentPane;
	private LoginTextField loginField;
	private PasswordTextField passwordField;

	private Timer animation;
	private FadingPanel glassPane;

	public LoginDialog() {
		super((JFrame) null, true);
		glassPane = new FadingPanel(this);
		setGlassPane(glassPane);
		buildContentPane();
		buildLoginForm();
		startAnimation();
		setSize(new Dimension(300, 200));
		setResizable(false);
		setLocationRelativeTo(null);
	}

	private void buildContentPane() {
		contentPane = new CurvesPanel();
		contentPane.setLayout(new BorderLayout());
		setContentPane(contentPane);
	}

	private void startAnimation() {
		animation = new Timer(50, new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				contentPane.repaint();
			}
		});

		animation.start();
	}

	private void buildLoginForm() {
		JPanel form = new JPanel(new GridBagLayout());

		form.add(new JLabel(),
				new GridBagConstraints(0, 0, 1, 1, 0.0, 0.3,
						GridBagConstraints.SOUTH, GridBagConstraints.NONE,
						new Insets(12, 36, 11, 7), 0, 0));

		loginField = new LoginTextField();
		form.add(loginField, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0,
				GridBagConstraints.NORTHEAST, GridBagConstraints.NONE,
				new Insets(0, 36, 5, 11), 0, 0));

		passwordField = new PasswordTextField();
		form.add(passwordField, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.7,
				GridBagConstraints.NORTHEAST, GridBagConstraints.NONE,
				new Insets(0, 36, 11, 11), 0, 0));
		passwordField.addActionListner(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				final String userName = loginField.getText();
				if(userName == null || "".equals(userName)) {
					loginField.alert();
					return ;
				}
				final String password = passwordField.getText();
				if(password == null || "".equals(password)) {
					passwordField.alert();
					return ;
				}
				loginField.normal();
				passwordField.normal();
				glassPane.setVisible(true);
				new Thread() {
					public void run() {
						try {
							final Authenticater authenticater = new Authenticater();
							authenticater.addLoginListener(new LoginListener() {

								/**
								 * Called by the <strong>JXLoginPanel</strong> in
								 * the event of a login failure
								 * @param source panel that fired the event
								 */
								public void loginFailed(LoginEvent source) {
									glassPane.setVisible(false);
									loginField.alert();
									passwordField.alert();
								}

								/**
								 * Called by the <strong>JXLoginPanel</strong> when
								 * the Authentication operation is started.
								 * 
								 * @param source panel that fired the event
								 */
								public void loginStarted(LoginEvent source) {
								}

								/**
								 * Called by the <strong>JXLoginPanel</strong> in
								 * the event of a login cancellation by the user.
								 * 
								 * @param source panel that fired the event
								 */
								public void loginCanceled(LoginEvent source) {
									 glassPane.setVisible(false);
								}

								/**
								 * Called by the <strong>JXLoginPanel</strong> in
								 * the event of a successful login.
								 * 
								 * @param source panel that fired the event
								 */
								public void loginSucceeded(LoginEvent source) {
									glassPane.setVisible(false);
									setVisible(false);
								}
							});

							try {
								authenticater.authenticate(userName, password, null);
							} catch (Exception e) {
								e.printStackTrace();
							}
						} catch (Exception e) {
							e.printStackTrace();
							glassPane.setVisible(false);
							loginField.alert();
							passwordField.alert();
						}
					}
				}.start();
			}
		});

		form.setOpaque(false);
		contentPane.add(form, BorderLayout.CENTER);
	}

	public void fadeInFinished() {
		glassPane.setVisible(false);
	}

	public void fadeOutFinished() {

		SwingUtilities.invokeLater(new Runnable() {

			public void run() {
				contentPane = new CirclesPanel();
				contentPane.setLayout(new BorderLayout());
				WaitAnimation waitAnimation = new WaitAnimation();
				contentPane.add(waitAnimation, BorderLayout.CENTER);
				setContentPane(contentPane);
				validate();
				glassPane.switchDirection();
			}
		});
	}

	public String getTitle() {
		return "Login...";
	}

	public static void main(String[] args) {
		LoginDialog frame = new LoginDialog();
		frame.setVisible(true);
	}

}
